/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package webservice.notafiscaleletronica.status;

import br.inf.portalfiscal.www.nfe.wsdl.nfestatusservico2.NfeStatusServico2Stub;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.commons.httpclient.protocol.Protocol;
import webservice.notafiscaleletronica.socket.SocketFactoryDinamico;

/**
 *
 * @author Icaro
 */
public class NFeStatusServicoFactoryDinamicoA1 {

    private static final int SSL_PORT = 443;

    public void NFeStatusServicoFactoryDinamicoA1(int codIbge){
    
        try {

            String codigoDoEstado = String.valueOf(codIbge);

            URL url = new URL("https://homologacao.nfe.sefazvirtual.rs.gov.br/ws/NfeStatusServico/NfeStatusServico2.asmx");

            /**
             * Informações do Certificado Digital A3.
             */
            String caminhoDoCertificadoDoCliente = "C:\\Seloma\\Certificados\\Certificado.pfx";
            String senhaDoCertificado = "oox4Foth";
            String arquivoCacertsGeradoTodosOsEstados = "C:\\Seloma\\Certificados\\NFeCacerts";

            InputStream entrada = new FileInputStream(caminhoDoCertificadoDoCliente);
            KeyStore ks = KeyStore.getInstance("pkcs12");
            try {
                ks.load(entrada, senhaDoCertificado.toCharArray());
            } catch (IOException e) {
                throw new Exception("Senha do Certificado Digital esta incorreta ou Certificado inválido.");
            }

            /**
             * Resolve o problema do 403.7 Forbidden para Certificados A3 e A1 e
             * elimina o uso das cofigurações: -
             * System.setProperty("javax.net.ssl.keyStore", "NONE"); -
             * System.setProperty("javax.net.ssl.keyStoreType", "PKCS11"); -
             * System.setProperty("javax.net.ssl.keyStoreProvider",
             * "SunPKCS11-SmartCard"); -
             * System.setProperty("javax.net.ssl.trustStoreType", "JKS"); -
             * System.setProperty("javax.net.ssl.trustStore",
             * arquivoCacertsGeradoTodosOsEstados);
             */
            String alias = "";
            Enumeration<String> aliasesEnum = ks.aliases();
            while (aliasesEnum.hasMoreElements()) {
                alias = (String) aliasesEnum.nextElement();
                if (ks.isKeyEntry(alias)) {
                    break;
                }
            }
            X509Certificate certificate = (X509Certificate) ks.getCertificate(alias);
            PrivateKey privateKey = (PrivateKey) ks.getKey(alias, senhaDoCertificado.toCharArray());
            SocketFactoryDinamico socketFactoryDinamico = new SocketFactoryDinamico(certificate, privateKey);
            socketFactoryDinamico.setFileCacerts(arquivoCacertsGeradoTodosOsEstados);

            Protocol protocol = new Protocol("https", socketFactoryDinamico, SSL_PORT);
            Protocol.registerProtocol("https", protocol);

            /**
             * Xml de Consulta.
             */
            StringBuilder xml = new StringBuilder();
            xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
                    .append("<consStatServ versao=\"2.00\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">")
                    .append("<tpAmb>2</tpAmb>")
                    .append("<cUF>")
                    .append(codigoDoEstado)
                    .append("</cUF>")
                    .append("<xServ>STATUS</xServ>")
                    .append("</consStatServ>");

            OMElement ome = AXIOMUtil.stringToOM(xml.toString());
            NfeStatusServico2Stub.NfeDadosMsg dadosMsg = new NfeStatusServico2Stub.NfeDadosMsg();
            dadosMsg.setExtraElement(ome);

            NfeStatusServico2Stub.NfeCabecMsg nfeCabecMsg = new NfeStatusServico2Stub.NfeCabecMsg();
            /**
             * Código do Estado.
             */
            nfeCabecMsg.setCUF(codigoDoEstado);

            /**
             * Versao do XML
             */
            nfeCabecMsg.setVersaoDados("2.00");
            NfeStatusServico2Stub.NfeCabecMsgE nfeCabecMsgE = new NfeStatusServico2Stub.NfeCabecMsgE();
            nfeCabecMsgE.setNfeCabecMsg(nfeCabecMsg);

            NfeStatusServico2Stub stub = new NfeStatusServico2Stub(url.toString());
            NfeStatusServico2Stub.NfeStatusServicoNF2Result result = stub.nfeStatusServicoNF2(dadosMsg, nfeCabecMsgE);

            info(result.getExtraElement().toString());

        } catch (Exception e) {
            error(e.toString());
        }
    }

    /**
     * Log Info.
     *
     * @param log
     */
    private static void info(String log) {
        System.out.println("INFO: " + log);
    }

    /**
     * Log Error.
     *
     * @param log
     */
    private static void error(String log) {
        System.out.println("ERROR: " + log);
    }
}
